package dao

import (
	"context"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gtime"

	"goldtree/internal/entity"
)

// StockPoolDao 股票池数据访问对象
type StockPoolDao struct{}

var StockPool = StockPoolDao{}

// Insert 创建股票池
func (dao *StockPoolDao) Insert(ctx context.Context, pool *entity.StockPool) (int64, error) {
	// 排除ID字段，让数据库自动生成
	result, err := g.DB().Model("stock_pools").Ctx(ctx).Data(pool).OmitEmpty().Insert()
	if err != nil {
		return 0, err
	}
	return result.LastInsertId()
}

// Update 更新股票池
func (dao *StockPoolDao) Update(ctx context.Context, id int, pool *entity.StockPool) error {
	pool.UpdatedAt = gtime.Now()
	_, err := g.DB().Model("stock_pools").Ctx(ctx).Where("id", id).Data(pool).Update()
	return err
}

// Delete 删除股票池
func (dao *StockPoolDao) Delete(ctx context.Context, id int) error {
	// 先删除股票池成员
	_, err := g.DB().Model("stock_pool_members").Ctx(ctx).Where("pool_id", id).Delete()
	if err != nil {
		return err
	}
	
	// 删除股票池规则
	_, err = g.DB().Model("stock_pool_rules").Ctx(ctx).Where("pool_id", id).Delete()
	if err != nil {
		return err
	}
	
	// 删除股票池
	_, err = g.DB().Model("stock_pools").Ctx(ctx).Where("id", id).Delete()
	return err
}

// GetById 根据ID获取股票池
func (dao *StockPoolDao) GetById(ctx context.Context, id int) (*entity.StockPool, error) {
	var pool *entity.StockPool
	err := g.DB().Model("stock_pools").Ctx(ctx).Where("id", id).Scan(&pool)
	if err != nil {
		return nil, err
	}
	return pool, nil
}

// GetByName 根据名称获取股票池
func (dao *StockPoolDao) GetByName(ctx context.Context, name string) (*entity.StockPool, error) {
	var pool *entity.StockPool
	err := g.DB().Model("stock_pools").Ctx(ctx).Where("name", name).Scan(&pool)
	if err != nil {
		return nil, err
	}
	return pool, nil
}

// GetList 获取股票池列表
func (dao *StockPoolDao) GetList(ctx context.Context, page, limit int, conditions ...interface{}) ([]*entity.StockPool, error) {
	model := g.DB().Model("stock_pools").Ctx(ctx)
	
	// 添加查询条件
	if len(conditions) > 0 {
		model = model.Where(conditions[0], conditions[1:]...)
	}
	
	var pools []*entity.StockPool
	err := model.Order("created_at DESC").Limit((page-1)*limit, limit).Scan(&pools)
	if err != nil {
		return nil, err
	}
	return pools, nil
}

// GetCount 获取股票池总数
func (dao *StockPoolDao) GetCount(ctx context.Context, conditions ...interface{}) (int, error) {
	model := g.DB().Model("stock_pools").Ctx(ctx)
	
	// 添加查询条件
	if len(conditions) > 0 {
		model = model.Where(conditions[0], conditions[1:]...)
	}
	
	count, err := model.Count()
	if err != nil {
		return 0, err
	}
	return count, nil
}

// GetActivePools 获取激活的股票池列表
func (dao *StockPoolDao) GetActivePools(ctx context.Context) ([]*entity.StockPool, error) {
	var pools []*entity.StockPool
	err := g.DB().Model("stock_pools").Ctx(ctx).Where("is_active", true).Order("created_at DESC").Scan(&pools)
	if err != nil {
		return nil, err
	}
	return pools, nil
}

// IsNameExists 检查股票池名称是否存在
func (dao *StockPoolDao) IsNameExists(ctx context.Context, name string) (bool, error) {
	count, err := g.DB().Model("stock_pools").Ctx(ctx).Where("name", name).Count()
	if err != nil {
		return false, err
	}
	return count > 0, nil
}

// StockPoolMemberDao 股票池成员数据访问对象
type StockPoolMemberDao struct{}

var StockPoolMember = StockPoolMemberDao{}

// Insert 添加股票池成员
func (dao *StockPoolMemberDao) Insert(ctx context.Context, member *entity.StockPoolMember) (int64, error) {
	result, err := g.DB().Model("stock_pool_members").Ctx(ctx).Data(member).OmitEmpty().Insert()
	if err != nil {
		return 0, err
	}
	return result.LastInsertId()
}

// BatchInsert 批量添加股票池成员
func (dao *StockPoolMemberDao) BatchInsert(ctx context.Context, members []*entity.StockPoolMember) error {
	_, err := g.DB().Model("stock_pool_members").Ctx(ctx).Data(members).Insert()
	return err
}

// Delete 删除股票池成员
func (dao *StockPoolMemberDao) Delete(ctx context.Context, id int) error {
	_, err := g.DB().Model("stock_pool_members").Ctx(ctx).Where("id", id).Delete()
	return err
}

// DeleteByPoolAndStock 根据股票池ID和股票代码删除成员
func (dao *StockPoolMemberDao) DeleteByPoolAndStock(ctx context.Context, poolId int, stockCode string) error {
	_, err := g.DB().Model("stock_pool_members").Ctx(ctx).
		Where("pool_id", poolId).
		Where("stock_code", stockCode).
		Delete()
	return err
}

// GetListByPoolId 根据股票池ID获取成员列表
func (dao *StockPoolMemberDao) GetListByPoolId(ctx context.Context, poolId int, page, limit int) ([]*entity.StockPoolMember, error) {
	var members []*entity.StockPoolMember
	
	if page > 0 && limit > 0 {
		err := g.DB().Model("stock_pool_members").Ctx(ctx).
			Where("pool_id", poolId).
			Order("added_at DESC").
			Limit((page-1)*limit, limit).
			Scan(&members)
		return members, err
	} else {
		// 不分页，获取所有成员
		err := g.DB().Model("stock_pool_members").Ctx(ctx).
			Where("pool_id", poolId).
			Order("added_at DESC").
			Scan(&members)
		return members, err
	}
}

// GetCountByPoolId 根据股票池ID获取成员总数
func (dao *StockPoolMemberDao) GetCountByPoolId(ctx context.Context, poolId int) (int, error) {
	count, err := g.DB().Model("stock_pool_members").Ctx(ctx).Where("pool_id", poolId).Count()
	if err != nil {
		return 0, err
	}
	return count, nil
}

// IsMemberExists 检查股票是否已在股票池中
func (dao *StockPoolMemberDao) IsMemberExists(ctx context.Context, poolId int, stockCode string) (bool, error) {
	count, err := g.DB().Model("stock_pool_members").Ctx(ctx).
		Where("pool_id", poolId).
		Where("stock_code", stockCode).
		Count()
	if err != nil {
		return false, err
	}
	return count > 0, nil
}

// UpdateWeight 更新股票池成员权重
func (dao *StockPoolMemberDao) UpdateWeight(ctx context.Context, id int, weight float64) error {
	_, err := g.DB().Model("stock_pool_members").Ctx(ctx).
		Where("id", id).
		Data(g.Map{"weight": weight}).
		Update()
	return err
}

// StockPoolRuleDao 股票池规则数据访问对象
type StockPoolRuleDao struct{}

var StockPoolRule = StockPoolRuleDao{}

// Insert 创建股票池规则
func (dao *StockPoolRuleDao) Insert(ctx context.Context, rule *entity.StockPoolRule) (int64, error) {
	result, err := g.DB().Model("stock_pool_rules").Ctx(ctx).Data(rule).OmitEmpty().Insert()
	if err != nil {
		return 0, err
	}
	return result.LastInsertId()
}

// Update 更新股票池规则
func (dao *StockPoolRuleDao) Update(ctx context.Context, id int, rule *entity.StockPoolRule) error {
	rule.UpdatedAt = gtime.Now()
	_, err := g.DB().Model("stock_pool_rules").Ctx(ctx).Where("id", id).Data(rule).Update()
	return err
}

// Delete 删除股票池规则
func (dao *StockPoolRuleDao) Delete(ctx context.Context, id int) error {
	_, err := g.DB().Model("stock_pool_rules").Ctx(ctx).Where("id", id).Delete()
	return err
}

// GetById 根据ID获取股票池规则
func (dao *StockPoolRuleDao) GetById(ctx context.Context, id int) (*entity.StockPoolRule, error) {
	var rule *entity.StockPoolRule
	err := g.DB().Model("stock_pool_rules").Ctx(ctx).Where("id", id).Scan(&rule)
	if err != nil {
		return nil, err
	}
	return rule, nil
}

// GetListByPoolId 根据股票池ID获取规则列表
func (dao *StockPoolRuleDao) GetListByPoolId(ctx context.Context, poolId int) ([]*entity.StockPoolRule, error) {
	var rules []*entity.StockPoolRule
	err := g.DB().Model("stock_pool_rules").Ctx(ctx).
		Where("pool_id", poolId).
		Order("priority ASC, created_at DESC").
		Scan(&rules)
	if err != nil {
		return nil, err
	}
	return rules, nil
}

// GetActiveRulesByPoolId 根据股票池ID获取激活的规则列表
func (dao *StockPoolRuleDao) GetActiveRulesByPoolId(ctx context.Context, poolId int) ([]*entity.StockPoolRule, error) {
	var rules []*entity.StockPoolRule
	err := g.DB().Model("stock_pool_rules").Ctx(ctx).
		Where("pool_id", poolId).
		Where("is_active", true).
		Order("priority ASC, created_at DESC").
		Scan(&rules)
	if err != nil {
		return nil, err
	}
	return rules, nil
}